package edu.sdjzu.exam.service.cheat.impl;


import cn.dev33.satoken.stp.StpUtil;

import edu.sdjzu.exam.domain.cheat.CheatingRecord;
import edu.sdjzu.exam.domain.examSession.Answer;
import edu.sdjzu.exam.dto.cheat.MarkCheatingDTO;
import edu.sdjzu.exam.mapper.examSession.AnswerMapper;
import edu.sdjzu.exam.mapper.examSession.CheatingRecordMapper;
import edu.sdjzu.exam.service.cheat.CheatingService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.similarity.CosineSimilarity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class CheatingServiceImpl implements CheatingService {

    private final AnswerMapper answerMapper;
    private final CheatingRecordMapper cheatingRecordMapper;

    @Override
    @Transactional
    public void markCheating(MarkCheatingDTO markDTO) {
        CheatingRecord record = new CheatingRecord();
        record.setSessionId(markDTO.getSessionId());
        record.setStudentId(StpUtil.getLoginIdAsLong());
        record.setExamId(0L); // 需要从 Exam_Sessions 获取
        record.setIsSuspected(markDTO.getIsSuspected());
        record.setReasons(markDTO.getReasons());
        record.setComments(markDTO.getComments());
        record.setMarkedBy(StpUtil.getLoginIdAsLong());
        record.setMarkedAt(LocalDateTime.now());
        cheatingRecordMapper.insertCheatingRecord(record);
    }

    @Override
    public void detectAnswerSimilarity(Long examId) {
        List<Answer> answers = answerMapper.selectAnswersByExamId(examId);
        CosineSimilarity cosineSimilarity = new CosineSimilarity();
        for (int i = 0; i < answers.size(); i++) {
            for (int j = i + 1; j < answers.size(); j++) {
                Answer a1 = answers.get(i);
                Answer a2 = answers.get(j);
                if (a1.getQuestionId().equals(a2.getQuestionId()) && a1.getAnswerContent() != null && a2.getAnswerContent() != null) {
                    Map<CharSequence, Integer> vector1 = toVector(a1.getAnswerContent());
                    Map<CharSequence, Integer> vector2 = toVector(a2.getAnswerContent());
                    double similarity = cosineSimilarity.cosineSimilarity(vector1, vector2);
                    if (similarity > 0.8) {
                        CheatingRecord record = new CheatingRecord();
                        record.setSessionId(a1.getSessionId());
                        record.setStudentId(a1.getStudentId());
                        record.setExamId(examId);
                        record.setIsSuspected(true);
                        record.setReasons("answer_similarity");
                        record.setComments("答案相似度: " + similarity);
                        record.setMarkedBy(0L); // 系统标记
                        record.setMarkedAt(LocalDateTime.now());
                        cheatingRecordMapper.insertCheatingRecord(record);
                    }
                }
            }
        }
    }

    private Map<CharSequence, Integer> toVector(String text) {
        Map<CharSequence, Integer> vector = new HashMap<>();
        String[] words = text.toLowerCase().split("\\s+");
        for (String word : words) {
            vector.put(word, vector.getOrDefault(word, 0) + 1);
        }
        return vector;
    }
}
